

from django.shortcuts import render

# Create your views here.
from django.views import View

from apps.verifications import constant
from apps.verifications.constant import IMAGE_CODE_EXPIRE_TIME, SMS_CODE_EXPIRES_TIME
from libs.yuntongxun.sms import CCP
from utils.response_code import RETCODE

'''
图片验证码
    1.我们通过capatcha 来生成图片和获取图片的内容（nxaz）
    2.把生成的图片内容保存起来（以方便在短信的地方进行验证 验证用户输入的是否和我们保存的一致）
        图片验证码有时效
        图片保存在redis中 可以减少 数据库的操作（如果把图片保存在数据库中，则增加了数据库的操作）

        key； value

        key使用uuid
        value 是保存  生成的随机码


短信验证码
    我们不需要认证成为开发者

     1.到平台中测试
     2.添加测试账号(只能给测试手机发送短信）
'''




# 2.将图片验证码的内容保存到redis中
# 3.返回图片
# content_type 所对应的是MIME类型
# 语法形式：大类/小类
# image/jpeg  image/png  image/gif
# text/html text/css text/javascript

from django_redis import get_redis_connection
from libs.captcha.captcha import captcha
from django import http

class ImageCodeView(View):
    """图形验证码"""

    def get(self, request, uuid):
        """
        :param request: 请求对象
        :param uuid: 唯一标识图形验证码所属于的用户
        :return: image/jpeg
        """
        # 生成图片验证码
        text,image = captcha.generate_captcha()

        # 保存图片验证码
        redis_conn = get_redis_connection('code')
        # 有效期
        redis_conn.setex('img_%s' % uuid, IMAGE_CODE_EXPIRE_TIME, text)

        # 响应图片验证码
        return http.HttpResponse(image, content_type='image/jpeg')


'''
一.把需求写下来
    作为用户会干什么:  输入手机号和图片验证码之后，点击获取短信验证码
    前段收集什么数据:  手机号，用户输入的图片验证码以及uuid
    后端实现什么功能：   实现验证发送短信


二.详细分析后端逻辑
    1.接受数据
    2.验证数据
    3.提取redis中的验证码
    4.删除redis中的验证码
    5.比对用户输入的验证码和redis的是否一致
    6.生成随机验证码
    7.把生成的短信验证码保存在redis中
    8.容联云发送短信
    9.返回响应


三.确定请求方式和路由
    GET     sms_code/mobile/?image_code=xxxx&image_code_id=xxx


    get
    1.提取URL的特定部分，如/weather/beijing/2018,可以在服务器端的路由中用正则表达式截取;
     sms_code/mobile/image_code/uuid
    2.查询字符串(query string), 形如key=value1&key=value2;
     sms_cosde/?mobile=xxx&image_code=xxxx&uuid=xxxx

    post
    发送json数据     在请求体里面    sms_code/
'''

class SmsCodeView(View):
    def get(self,request,mobile):

        image_text = request.GET.get('image_code')
        uuid = request.GET.get('image_code_id')

        if not all([image_text, uuid]):
            return http.JsonResponse({'code': RETCODE.NECESSARYPARAMERR , 'errmsg': '缺少必传参数'})
        # 提取redis中的验证码
        redis_conn = get_redis_connection('code')
        redis_text = redis_conn.get('img_%s' % uuid)


        if redis_text is None:
            # 图形验证码过期
            return http.JsonResponse({'code':RETCODE.IMAGECODEERR , 'errmsg': '图形验证码错误'})
        # 删除验证码
        redis_conn.delete('img_%s'% uuid)

        # 比对redis数据库的信息
        if  redis_text.decode().lower() != image_text.lower():
            return http.JsonResponse({'code':RETCODE.IMAGECODEERR,'errmsg': '图形验证码错误'})
        # 先判断标记位
        send_flag = redis_conn.get('send_flag_%s'%mobile)
        if send_flag:
            return http.JsonResponse({'code':RETCODE.THROTTLINGERR,'errmsg': '操作太频繁'})
        from random import randint
        # 生成短信验证码：生成6位数验证码
        sms_code='%06d' % randint(0, 999999)


        # 采用管道
        # 1.创建管道
        pipe = redis_conn.pipeline()
        # 2.保存短信验证码 (将redis数据缓存到管道中去)
        pipe.setex('sms_%s'%mobile,SMS_CODE_EXPIRES_TIME,sms_code)
        pipe.setex('send_flag_%s'%mobile,60,1)
        # 3.让管道执行指令
        pipe.execute()
        # 发送短信验证码
        # CCP().send_template_sms(mobile, [sms_code, SMS_CODE_EXPIRES_MINUTE],SMS_CODE_TEMPLATE_ID)
        from celery_tasks.sms.tasks import send_sms_code
        send_sms_code.delay(mobile,sms_code)

        return http.JsonResponse({'code': 0, 'errmsg': '发送短信成功'})

